package com.heny.demo.handler;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
import org.locationtech.jts.io.WKTWriter;
import org.postgresql.util.PGobject;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class GeometryTypeHandler extends BaseTypeHandler<Point> {

    private final GeometryFactory geometryFactory = new GeometryFactory();
    private final WKTReader wktReader = new WKTReader(geometryFactory);
    private final WKTWriter wktWriter = new WKTWriter();

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Point point, JdbcType jdbcType) throws SQLException {
        PGobject pGobject = new PGobject();
        pGobject.setType("geometry");
        pGobject.setValue(wktWriter.write(point));
        ps.setObject(i, pGobject);
    }

    @Override
    public Point getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String wkt = rs.getString(columnName);
        if (wkt == null) return null;
        try {
            Geometry geom = wktReader.read(wkt);
            return (Point) geom;
        } catch (ParseException e) {
            throw new SQLException("Failed to parse WKT into Point", e);
        }
    }

    @Override
    public Point getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String wkt = rs.getString(columnIndex);
        if (wkt == null) return null;
        try {
            Geometry geom = wktReader.read(wkt);
            return (Point) geom;
        } catch (ParseException e) {
            throw new SQLException("Failed to parse WKT into Point", e);
        }
    }

    @Override
    public Point getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String wkt = cs.getString(columnIndex);
        if (wkt == null) return null;
        try {
            Geometry geom = wktReader.read(wkt);
            return (Point) geom;
        } catch (ParseException e) {
            throw new SQLException("Failed to parse WKT into Point", e);
        }
    }
}